1540. 23 из 5
Можно ли так расставить 5
заданных чисел и знаки арифметических операций (+, -, *), чтобы получилось
выражение, значение которого равно 23? Считать, что все три указанные операции
имеют одинаковый приоритет и выполняются последовательно слева направо.
Вход. Каждая строка содержит пять натуральных
чисел от 1 до 50. Последняя строка содержит пять нулей и не обрабатывается.
Выход. Для
каждого теста вывести в отдельной строке слово “Possible”, если можно так расставить числа и
знаки указанных арифметических операций, чтобы получилось выражение со
значением 23. Если этого сделать не возможно, то вывести “Impossible”.
Пример входа |
Пример выхода |
1 1 1
1 1 1 2 3
4 5 2 3 5
7 11 0 0 0
0 0 |
Impossible Possible Possible |
комбинаторика – перебор вариантов
Генерируем все
перестановки входных чисел. Для каждой перестановки между числами расставляем
все возможные знаки арифметических операций и вычисляем полученные выражения.
Если хотя бы одно выражение имеет значение 23, то устанавливаем переменную flag в 1 и
заканчиваем обработку текущего теста.
Входную пятерку
чисел храним в целочисленном массиве a. Переменная flag
принимает значение 1, если найдено выражение со значением 23, иначе flag = 0.
int a[5], flag;
Функция RunSum
вычисляет значение выражения, операнды которого находятся в массиве a. Между
операндами вставляются знаки всевозможных операций и вычисляются полученные
выражения при помощи техники бектрекинга.
Если значение одного из выражений равно 23, то функция возвращает 1, иначе 0.
int
RunSum(int Sum, int
index)
{
if (index ==
5)
if (Sum ==
23) return 1; else
return 0;
if
(RunSum(Sum+a[index],index+1)) return 1;
if
(RunSum(Sum-a[index],index+1)) return 1;
if
(RunSum(Sum*a[index],index+1)) return 1;
return 0;
}
Основная часть
программы. Читаем пятерку чисел в массив a. Запускаем процедуру генерации всех
перестановок. Поскольку функция next_permutation генерирует
перестановки в лексикографическом порядке, то первой должна быть наименьшая
перестановка. Наименьшей будет перестановка, у которой числа образуют
неубывающую последовательность. То есть перед генерацией перестановок числа в
массиве а следует отсортировать по неубыванию (если этого не сделать, то могут
быть рассмотрены не все перестановки).
while(scanf("%d %d %d %d %d",
&a[0],&a[1],&a[2],&a[3],&a[4]),a[0]+a[1]+a[2]+a[3]+a[4])
{
sort(a,a+5);
flag = 0;
do{
Для каждой
перестановки запускаем функцию RunSum, которая выясняет, можно ли
между числами этой перестановки расставить знаки операций так, чтобы получить
значение 23.
if (flag =
RunSum(a[0],1)) break;
} while(next_permutation(a,a+5));
Если переменная flag установилась в 1, то выводим “Possible”, иначе выводим “Impossible”.
if (flag)
printf("Possible\n"); else printf("Impossible\n");
memset(a,0,sizeof(a));
}